namespace Core.Features
{
    using System;
    using Base;
    using Contracts.Enums;
    using Resources;
    using Core.Contracts.Interfaces;
    using System.Linq;

    
    public sealed class ShieldAbsorptionRatio<T>: FeatureBase<object>
    {
        public ShieldAbsorptionRatio(){}

        public ShieldAbsorptionRatio(T value) 
            : base(value){ }
        /// <summary>
        /// Obtains the feature name
        /// </summary>
        public override string Name
        {
            get { return "Shield absorption ratio"; }
        }
        /// <summary>
        /// Obtains the feature group
        /// </summary>
        public override FeatureGroupsEnum FeatureGroup{ get { return FeatureGroupsEnum.Defence; } }
        /// <summary>
        /// Obtains the feature type
        /// </summary>
        public override FeaturesEnum FeatureType { get { return FeaturesEnum.ShieldAbsorptionRatio; } }
        /// <summary>
        /// Obtains or defines the feature unit
        /// </summary>
        public override string Unit { get { return Traduction.label_unit_APHP; } }

        public override void SetModifiedValue(IAgent agent, IRobot robot)
        {
            if (agent == null || robot == null) return;

           

            // Bonus from Extensions
            double extensionBonus = agent.Extensions.SumModifiersValues(FeatureTypesEnum.Module, this.FeatureType);
            // Bonus from bots
            double robotBonus = robot.Modifiers.SumModifiersValues(agent.Extensions, FeatureTypesEnum.Module, this.FeatureType);
            // ShieldHardeners modules
            double moduleBonus = robot.Modules.SumModifiersValues(FeatureTypesEnum.Module, this.FeatureType, ModuleGroupsEnum.ShieldHardeners);
            // ShieldRadius modules
            double shieldRadius = robot.Modules.SumModifiersValues(FeatureTypesEnum.Module, this.FeatureType, ModuleGroupsEnum.ShieldGenerators);
            // SurfaceHitSize
            var botsurfacesize = robot.Features.Where(f => f.FeatureType == FeaturesEnum.SurfaceHitSize).FirstOrDefault().IsModified
               ? (double)robot.Features.Where(f => f.FeatureType == FeaturesEnum.SurfaceHitSize).FirstOrDefault().ModifiedValue
                       : (double)robot.Features.Where(f => f.FeatureType == FeaturesEnum.SurfaceHitSize).FirstOrDefault().Value;

            double temp = (((double)Value / (1 + (Math.Abs(extensionBonus) + Math.Abs(robotBonus))) / (shieldRadius) * (botsurfacesize)));

            // Bonus from Hardener modules
            temp = robot.Modules.Aggregate(
                temp,
                (current, mod) => current / (1 + Math.Abs(mod.Value)),
                FeatureTypesEnum.Module,
                this.FeatureType,
                ModuleGroupsEnum.ShieldHardeners);

            // nexus Bonus
            double nexusBonus = robot.Modules.SumModifiersValues(FeatureTypesEnum.Robot, this.FeatureType, ModuleGroupsEnum.NexusModuleShield);
            double nexusSkillBonus = agent.Extensions.SumModifiersValues(FeatureTypesEnum.Robot, this.FeatureType);

            double nexusTotalBonus = 0;

            if (nexusBonus != 0)

                nexusTotalBonus = Math.Abs(nexusBonus) + (((1 + Math.Abs(nexusBonus)) * Math.Abs(nexusSkillBonus)) / 100);

            temp = temp * (1 - nexusTotalBonus);


            ModifiedValue = IsRounded
                               ? Math.Round(temp, 0, MidpointRounding.AwayFromZero)
                               : Math.Round(temp, 3);
        }


    }
}